import { Component, OnInit, OnDestroy, ViewChild, TemplateRef, Inject } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { NzMessageService } from 'ng-zorro-antd'
import { forkJoin } from 'rxjs'
import { DOCUMENT } from '@angular/common'
import { PageScrollService } from 'ngx-page-scroll-core'
import { ACLService } from '@delon/acl'
import { deepCopy } from '@delon/util'

import { DetailBaseClass } from '@shared/classes/DetailBaseClass'
import { Acquirer, Institution, IUpdateAcquirerBaseInfo } from '@shared/interfaces/acquirer'
import { IDetailHeaderTab, StatusTextMap, BizAreaOptions, Currency } from '@shared/interfaces/common'
import { AcquirerService } from '../acquirer.service'
import { PageService } from '@shared/services/page.service'
import { CommonAcquirerService } from '@shared/services/acquirer.service'
import { ETabScrollStatus } from '@shared/enums'
import { CountryService } from '@shared/services/country.service'
import { compareTwoCountries } from 'app/utils/helpers'
import {
  emailReg,
  insNameENReg,
  insNameMaxLength,
  insNameENMaxLength,
  contactNameMaxLength,
  emailMaxLength,
} from 'app/utils/contraints'
import { Validators } from 'app/utils/validator'
import { DetailHeaderComponent } from '@shared/components/detail-header/detail-header.component'
import { ModalService } from '@shared/services/modal.service'
import { I18NService } from '@core'

@Component({
  selector: 'app-acquirer-detail',
  templateUrl: './detail.component.html',
})
export class AcquirerDetailComponent extends DetailBaseClass<Institution> implements OnInit, OnDestroy {
  imgSrc = 'assets/images/centaur/base-info-pic/ins.png'
  @ViewChild('tpCurrency') tpCurrency: TemplateRef<any>
  @ViewChild('tpCountry') tpCountry: TemplateRef<any>
  @ViewChild('tpControl') tpControl: TemplateRef<any>
  @ViewChild('tpBusArea') tpBusArea: TemplateRef<any>

  @ViewChild(DetailHeaderComponent) detailHeaderComponent: DetailHeaderComponent

  tabs: IDetailHeaderTab[] = [
    { text: this.trans('GENERAL.INFO.OTHER.TRADE_INFO'), url: './trades' },
    { text: this.trans('BIZ.ACQUIRER.OTHER.QR_CHANNELS'), url: './channels/qr' },
    { text: this.trans('BIZ.ACQUIRER.OTHER.CARD_CHANNELS'), url: './channels/card' },
    { text: this.trans('BIZ.ACQUIRER.OTHER.EC_CHANNELS'), url: './channels/ec' },
    { text: this.trans('GENERAL.INFO.OTHER.SETTLEMENT'), url: './settlement' },
    { text: this.trans('GENERAL.INFO.OTHER.ACQUIRER_FUNC_CONFIG'), url: './func/acquirer' },
    // { text: this.trans('GENERAL.INFO.OTHER.QR_FEATURES'), url: './func/qr' },
    // { text: '刷卡功能配置', url: './func/card' },
    { text: this.trans('GENERAL.INFO.OTHER.AUDIT_CONFIG'), url: './audit' },
    { text: this.trans('GENERAL.INFO.OTHER.USERS'), url: './users' },
  ]

  countries = []
  countryCompareFn = compareTwoCountries

  bizAreaOptions = BizAreaOptions

  // this variable use to test
  // tasks = [
  //   {
  //     userName: 'Abc Test',
  //     status: 'created',
  //     description: '创建微信交易记录',
  //     time: new Date(),
  //   },
  //   {
  //     userName: 'Abc Test1',
  //     status: 'updated',
  //     description: '修改了 评审时间，旧值为 "2019-01-09"，新值为 "0000-00-00"。',
  //     time: new Date(),
  //   },
  //   {
  //     userName: 'Abc Test2',
  //     status: 'updated',
  //     description: '修改了 抄送给，旧值为 ",jim.wang,michael.zhao,arturo.wang,cherry.zhou,dick.zhang,s…',
  //     time: new Date(),
  //   },
  //   {
  //     userName: 'Abc Test3',
  //     status: 'deleted',
  //     description: '删除了 评审时间，旧值为 "2019-01-09"，新值为 "0000-00-00"。',
  //     time: new Date(),
  //   }
  // ]

  constructor(
    public route: ActivatedRoute,
    public msg: NzMessageService,
    public pageService: PageService,
    public acquirerService: AcquirerService,
    public commonAcquirerService: CommonAcquirerService,
    public aclService: ACLService,
    private pageScrollService: PageScrollService,
    private countryService: CountryService,
    private modalService: ModalService,
    private i18n: I18NService,
    @Inject(DOCUMENT) private document: any,
  ) {
    super(pageService)
  }

  ngOnInit() {
    this.loading = true
    this.id = this.route.snapshot.params['id']
    this.initTabScroll()
    this.requestAll()
  }

  ngOnDestroy() {
    this.pageService.setTabScrollStatus(ETabScrollStatus.InitialLoad)
    this.pageService.triggerBaseEdit(false)
  }

  requestAll(): void {
    forkJoin(this.countryService.getCounties(), this.acquirerService.getOne(this.id)).subscribe(value => {
      const [countries, acquirer] = value
      this.countries = countries
      this.renderAcquirer(acquirer)
      this.saveDataToDataStore(acquirer)
      this.initialColumns()
      this.initColumns()
      this.loading = false
    })
  }

  initTabScroll(): void {
    this.pageService.tabScrollStatus$.subscribe(tabStatus => {
      this.pageScroll(ETabScrollStatus.InitialLoad)
    })
  }

  triggerBaseEdit(): void {
    this.copiedDetailData = this.copyDetailData(this.detailData)
    this.pageService.triggerBaseEdit(true)
  }

  initialColumns() {
    this.firstColumns = [
      {
        span: 8,
        index: 'common.insCode',
        label: 'GENERAL.INSTITUTION.CODE',
        labelI18n: 'GENERAL.INSTITUTION.CODE',
        disEditable: true,
      },
      {
        span: 8,
        index: 'common.insName',
        label: 'GENERAL.INSTITUTION.NAME',
        labelI18n: 'GENERAL.INSTITUTION.NAME',
        validator: {
          funcs: [Validators.required, Validators.maxLength(insNameMaxLength)],
          errorTips: [
            this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INSTITUTION.NAME') }),
            this.trans('VALIDATION.MAX_LENGTH', { length: insNameMaxLength }),
          ],
        },
      },
      {
        span: 8,
        index: 'common.insNameEN',
        label: 'GENERAL.INSTITUTION.NAME_EN',
        labelI18n: 'GENERAL.INSTITUTION.NAME_EN',
        validator: {
          funcs: [Validators.required, Validators.maxLength(insNameENMaxLength), Validators.pattern(insNameENReg)],
          errorTips: [
            this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INSTITUTION.NAME_EN') }),
            this.trans('VALIDATION.MAX_LENGTH', { length: insNameENMaxLength }),
            this.trans('VALIDATION.PATTERN.ALPHANUMERIC_SYMBOLS_ONLY'),
          ],
        },
      },
    ]

    this.secondColumns = [
      {
        span: 6,
        index: 'common.businessArea',
        label: 'BIZ.ACQUIRER.BIZ_AREA',
        labelI18n: 'BIZ.ACQUIRER.BIZ_AREA',
        template: this.tpBusArea,
      },
      {
        span: 6,
        index: 'common.address.nation',
        label: 'GENERAL.INFO.COUNTRY_REGION',
        labelI18n: 'GENERAL.INFO.COUNTRY_REGION',
        template: this.tpCountry,
      },
      {
        span: 6,
        index: 'common.currencies',
        label: 'GENERAL.INFO.TRANSACTION_CURRENCY',
        labelI18n: 'GENERAL.INFO.TRANSACTION_CURRENCY',
        pipe: this.parseCurValue.bind(this),
        template: this.tpCurrency,
      },
      {
        span: 6,
        index: 'common.status',
        label: 'GENERAL.INFO.STATUS',
        labelI18n: 'GENERAL.INFO.STATUS',
        pipe: status => this.trans(StatusTextMap[status]),
        disEditable: true,
      },
    ]

    this.bottomColumnsRows = [
      [
        {
          span: 12,
          index: 'common.contact.name',
          label: 'GENERAL.INFO.CONTACT_NAME',
          labelI18n: 'GENERAL.INFO.CONTACT_NAME',
          validator: {
            funcs: [Validators.required, Validators.maxLength(contactNameMaxLength)],
            errorTips: [
              this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.CONTACT_NAME') }),
              this.trans('VALIDATION.MAX_LENGTH', { length: contactNameMaxLength }),
            ],
          },
        },
        {
          span: 12,
          index: 'common.contact.email',
          label: 'GENERAL.INFO.EMAIL',
          labelI18n: 'GENERAL.INFO.EMAIL',
          validator: {
            funcs: [Validators.required, Validators.maxLength(emailMaxLength), Validators.pattern(emailReg)],
            errorTips: [
              this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.EMAIL') }),
              this.trans('VALIDATION.MAX_LENGTH', { length: emailMaxLength }),
              this.trans('VALIDATION.PATTERN.EMAIL'),
            ],
          },
        },
      ],
      [
        {
          span: 18,
          index: 'common.address.address',
          label: 'GENERAL.INFO.ADDRESS',
          labelI18n: 'GENERAL.INFO.ADDRESS',
          validator: {
            funcs: [Validators.required],
            errorTips: [this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.ADDRESS') })],
          },
        },
        {
          span: 6,
          label: 'GENERAL.INFO.OPERATION',
          labelI18n: 'GENERAL.INFO.OPERATION',
          template: this.tpControl,
          operate: true,
          acl: ['api.put.camel.institution.one.freeze'],
        },
      ]
    ]
  }

  renderAcquirer(acquirer: Acquirer): void {
    this.detailData = deepCopy(acquirer.institution)
  }

  renderAcquirerAfterUpdate(institution: Institution): void {
    this.detailData = institution
    this.initColumns()
  }

  saveDataToDataStore(acquirer: Acquirer): void {
    this.commonAcquirerService.setViewingAcquirer(acquirer)
  }

  reSaveDataToDataStoreAfterUpdate(institution: Institution): void {
    const viewingAcquirer = this.commonAcquirerService.viewingAcquirer
    viewingAcquirer.institution = institution
    this.commonAcquirerService.setViewingAcquirer(viewingAcquirer)
  }

  cancelBase(): void {
    const acquirer = this.commonAcquirerService.viewingAcquirer
    acquirer.institution = this.copiedDetailData
    this.renderAcquirer(acquirer)
    this.clearColumnsErrorTips()
    this.initColumns()
    this.pageService.triggerBaseEdit(false)
  }

  saveBase(): void {
    if (!this.checkEditValidation()) {
      this.msg.error(this.trans('GENERAL.NOTIFICATION.VALIDATION_FAIL'))
      return
    }
    try {
      this.detailHeaderComponent.hideButtons()
      this.pageService.triggerBaseEdit(false)
      this.updateColumns()
      const { version, common } = this.detailData
      const saveData: IUpdateAcquirerBaseInfo = {
        version,
        common,
      }
      this.loading = true
      this.acquirerService.updateBaseInfoOfAcquirer(saveData, common.insCode).subscribe(acquirer => {
        this.renderAcquirerAfterUpdate(acquirer.institution)
        this.reSaveDataToDataStoreAfterUpdate(acquirer.institution)
        this.clearColumnsErrorTips()
        this.loading = false
        this.msg.success(this.trans('GENERAL.NOTIFICATION.UPDATE_SUCCESS'))
      })
    } catch (err) {
      this.msg.error(this.trans('GENERAL.NOTIFICATION.UPDATE_FAIL'), err.message)
    }
  }

  parseCurValue(currencies: Array<Currency>): string {
    if (!currencies) return ''
    return currencies.map(c => c.code).sort().join('、')
  }

  freezeDialog(): void {
    const { insName } = this.detailData.common
    const msg = this.trans('GENERAL.NOTIFICATION.INSTITUTION_FREEZE_CONFIRM', { insName })
    this.modalService.freezeAndUnFreeze(msg).subscribe(isOK => {
      if (!isOK) return
      this.freeze()
    })
  }

  unfreezeDialog(): void {
    const { insName } = this.detailData.common
    const msg = this.trans('GENERAL.NOTIFICATION.INSTITUTION_UNFREEZE_CONFIRM', { insName })
    this.modalService.freezeAndUnFreeze(msg).subscribe(isOK => {
      if (!isOK) return
      this.unfreeze()
    })
  }

  freeze(): void {
    const { insCode } = this.detailData.common
    this.acquirerService.freeze(insCode).subscribe(
      success => {
        this.msg.success(this.trans('GENERAL.NOTIFICATION.FREEZE_SUCCESS'))
        this.requestAll()
      },
      () => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.FREEZE_FAIL'))
      },
    )
  }

  unfreeze(): void {
    const { insCode } = this.detailData.common
    this.acquirerService.unfreeze(insCode).subscribe(
      success => {
        this.msg.success(this.trans('GENERAL.NOTIFICATION.UNFREEZE_SUCCESS'))
        this.requestAll()
      },
      () => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.UNFREEZE_SUCCESS'))
      },
    )
  }

  private pageScroll(tabStatus: ETabScrollStatus): void {
    if (tabStatus === ETabScrollStatus.InitialLoad) {
      return
    } else {
      if (tabStatus === ETabScrollStatus.Stop) {
        return
      }
      this.pageScrollService.scroll({
        document: this.document,
        scrollTarget: '.cil__scroll-div',
      })
    }
  }

  currencyRequiredHandler(): void {
    this.msg.error(this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.TRANSACTION_CURRENCY') }))
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }
}
